#include "json_wrapper.h"
#include <string.h>

// ====================
// 内部结构定义
// ====================

/**
 * @struct JsonObject
 * @brief 封装cJSON对象的结构体
 *
 * @param cjson     指向底层cJSON对象的指针
 * @param auto_free 标记是否在释放时自动删除底层cJSON对象
 */
struct JsonObject
{
    cJSON *cjson;
    bool auto_free;
};

/**
 * @struct JsonArray
 * @brief 封装cJSON数组的结构体
 *
 * @param cjson     指向底层cJSON数组的指针
 * @param auto_free 标记是否在释放时自动删除底层cJSON数组
 */
struct JsonArray
{
    cJSON *cjson;
    bool auto_free;
};

// ====================
// 内存管理
// ====================

/**
 * @brief 释放JSON对象或数组占用的内存
 *
 * @param json 要释放的JsonObject或JsonArray指针
 *
 * 注意：如果auto_free为true，会同时释放底层的cJSON结构
 */
void json_free(void *json)
{
    if (!json)
        return;

    if (((JsonObject *)json)->auto_free)
    {
        cJSON_Delete(((JsonObject *)json)->cjson);
    }
    free(json);
}

// ====================
// 内部辅助函数
// ====================

/**
 * @brief 创建JsonObject结构
 *
 * @param cjson     底层cJSON对象
 * @param auto_free 是否自动管理内存
 * @return JsonObject* 创建的对象指针，失败返回NULL
 */
static JsonObject *create_json_object(cJSON *cjson, bool auto_free)
{
    if (!cjson)
        return NULL;

    JsonObject *obj = malloc(sizeof(JsonObject));
    if (!obj)
        return NULL;

    obj->cjson = cjson;
    obj->auto_free = auto_free;
    return obj;
}

/**
 * @brief 创建JsonArray结构
 *
 * @param cjson     底层cJSON数组
 * @param auto_free 是否自动管理内存
 * @return JsonArray* 创建的数组指针，失败返回NULL
 */
static JsonArray *create_json_array(cJSON *cjson, bool auto_free)
{
    if (!cjson)
        return NULL;

    JsonArray *array = malloc(sizeof(JsonArray));
    if (!array)
        return NULL;

    array->cjson = cjson;
    array->auto_free = auto_free;
    return array;
}

// ====================
// JSON 对象操作实现
// ====================

/**
 * @brief 创建一个空的JSON对象
 *
 * @return JsonObject* 新创建的JSON对象
 */
JsonObject *json_object_create()
{
    return create_json_object(cJSON_CreateObject(), true);
}

/**
 * @brief 从JSON字符串解析创建JSON对象
 *
 * @param json_str JSON格式的字符串
 * @return JsonObject* 解析后的JSON对象，失败返回NULL
 */
JsonObject *json_object_parse(const char *json_str)
{
    cJSON *cjson = cJSON_Parse(json_str);
    if (!cjson)
        return NULL;
    return create_json_object(cjson, true);
}

/**
 * @brief 将JSON对象序列化为字符串
 *
 * @param obj       要序列化的JSON对象
 * @param formatted 是否格式化输出（带缩进）
 * @return char*    序列化后的字符串，需调用free释放
 */
char *json_object_to_string(JsonObject *obj, bool formatted)
{
    if (!obj || !obj->cjson)
        return NULL;
    return formatted ? cJSON_Print(obj->cjson) : cJSON_PrintUnformatted(obj->cjson);
}

/**
 * @brief 将JSON对象保存到文件
 *
 * @param obj      要保存的JSON对象
 * @param filename 目标文件名
 * @return true    保存成功
 * @return false   保存失败
 */
bool json_object_save_to_file(JsonObject *obj, const char *filename)
{
    if (!obj || !obj->cjson || !filename)
        return false;

    char *json_str = cJSON_Print(obj->cjson);
    if (!json_str)
        return false;

    FILE *fp = fopen(filename, "w");
    if (!fp)
    {
        free(json_str);
        return false;
    }

    fputs(json_str, fp);
    fclose(fp);
    free(json_str);
    return true;
}

/**
 * @brief 向JSON对象添加字符串属性
 *
 * @param obj   JSON对象
 * @param key   属性键
 * @param value 字符串值
 */
void json_object_put_string(JsonObject *obj, const char *key, const char *value)
{
    if (obj && obj->cjson && key)
    {
        cJSON_AddStringToObject(obj->cjson, key, value);
    }
}

/**
 * @brief 向JSON对象添加数值属性
 *
 * @param obj   JSON对象
 * @param key   属性键
 * @param value 数值
 */
void json_object_put_number(JsonObject *obj, const char *key, double value)
{
    if (obj && obj->cjson && key)
    {
        cJSON_AddNumberToObject(obj->cjson, key, value);
    }
}

/**
 * @brief 向JSON对象添加布尔属性
 *
 * @param obj   JSON对象
 * @param key   属性键
 * @param value 布尔值
 */
void json_object_put_bool(JsonObject *obj, const char *key, bool value)
{
    if (obj && obj->cjson && key)
    {
        cJSON_AddBoolToObject(obj->cjson, key, value);
    }
}

/**
 * @brief 向JSON对象添加null属性
 *
 * @param obj JSON对象
 * @param key 属性键
 */
void json_object_put_null(JsonObject *obj, const char *key)
{
    if (obj && obj->cjson && key)
    {
        cJSON_AddNullToObject(obj->cjson, key);
    }
}

/**
 * @brief 向JSON对象添加子对象
 *
 * @param obj   JSON对象
 * @param key   属性键
 * @param value 子对象（所有权转移给父对象）
 */
void json_object_put_object(JsonObject *obj, const char *key, JsonObject *value)
{
    if (obj && obj->cjson && key && value && value->cjson)
    {
        cJSON_AddItemToObject(obj->cjson, key, value->cjson);
        value->auto_free = false; // 所有权转移
    }
}

/**
 * @brief 向JSON对象添加数组
 *
 * @param obj   JSON对象
 * @param key   属性键
 * @param value 数组（所有权转移给父对象）
 */
void json_object_put_array(JsonObject *obj, const char *key, JsonArray *value)
{
    if (obj && obj->cjson && key && value && value->cjson)
    {
        cJSON_AddItemToObject(obj->cjson, key, value->cjson);
        value->auto_free = false; // 所有权转移
    }
}

/**
 * @brief 从JSON对象获取字符串属性
 *
 * @param obj           JSON对象
 * @param key           属性键
 * @param default_value 默认值（当属性不存在或类型错误时返回）
 * @return const char*  字符串值
 */
const char *json_object_get_string(JsonObject *obj, const char *key, const char *default_value)
{
    if (!obj || !obj->cjson || !key)
        return default_value;

    cJSON *item = cJSON_GetObjectItem(obj->cjson, key);
    if (cJSON_IsString(item))
    {
        return item->valuestring;
    }
    return default_value;
}

/**
 * @brief 从JSON对象获取数值属性
 *
 * @param obj           JSON对象
 * @param key           属性键
 * @param default_value 默认值（当属性不存在或类型错误时返回）
 * @return double       数值
 */
double json_object_get_number(JsonObject *obj, const char *key, double default_value)
{
    if (!obj || !obj->cjson || !key)
        return default_value;

    cJSON *item = cJSON_GetObjectItem(obj->cjson, key);
    if (cJSON_IsNumber(item))
    {
        return item->valuedouble;
    }
    return default_value;
}

/**
 * @brief 从JSON对象获取布尔属性
 *
 * @param obj           JSON对象
 * @param key           属性键
 * @param default_value 默认值（当属性不存在或类型错误时返回）
 * @return bool         布尔值
 */
bool json_object_get_bool(JsonObject *obj, const char *key, bool default_value)
{
    if (!obj || !obj->cjson || !key)
        return default_value;

    cJSON *item = cJSON_GetObjectItem(obj->cjson, key);
    if (cJSON_IsBool(item))
    {
        return cJSON_IsTrue(item);
    }
    return default_value;
}

/**
 * @brief 从JSON对象获取子对象
 *
 * @param obj JSON对象
 * @param key 属性键
 * @return JsonObject* 子对象（不转移所有权），失败返回NULL
 */
JsonObject *json_object_get_object(JsonObject *obj, const char *key)
{
    if (!obj || !obj->cjson || !key)
        return NULL;

    cJSON *item = cJSON_GetObjectItem(obj->cjson, key);
    if (cJSON_IsObject(item))
    {
        return create_json_object(item, false);
    }
    return NULL;
}

/**
 * @brief 从JSON对象获取数组
 *
 * @param obj JSON对象
 * @param key 属性键
 * @return JsonArray* 数组（不转移所有权），失败返回NULL
 */
JsonArray *json_object_get_array(JsonObject *obj, const char *key)
{
    if (!obj || !obj->cjson || !key)
        return NULL;

    cJSON *item = cJSON_GetObjectItem(obj->cjson, key);
    if (cJSON_IsArray(item))
    {
        return create_json_array(item, false);
    }
    return NULL;
}

// ====================
// JSON 数组操作实现
// ====================

/**
 * @brief 创建一个空的JSON数组
 *
 * @return JsonArray* 新创建的JSON数组
 */
JsonArray *json_array_create()
{
    return create_json_array(cJSON_CreateArray(), true);
}

/**
 * @brief 从JSON字符串解析创建JSON数组
 *
 * @param json_str JSON格式的字符串
 * @return JsonArray* 解析后的JSON数组，失败返回NULL
 */
JsonArray *json_array_parse(const char *json_str)
{
    cJSON *cjson = cJSON_Parse(json_str);
    if (!cjson || !cJSON_IsArray(cjson))
    {
        if (cjson)
            cJSON_Delete(cjson);
        return NULL;
    }
    return create_json_array(cjson, true);
}

/**
 * @brief 获取JSON数组的大小
 *
 * @param array JSON数组
 * @return int  数组元素个数
 */
int json_array_size(JsonArray *array)
{
    if (!array || !array->cjson)
        return 0;
    return cJSON_GetArraySize(array->cjson);
}

/**
 * @brief 向JSON数组添加字符串元素
 *
 * @param array JSON数组
 * @param value 字符串值
 */
void json_array_append_string(JsonArray *array, const char *value)
{
    if (array && array->cjson)
    {
        cJSON_AddItemToArray(array->cjson, cJSON_CreateString(value));
    }
}

/**
 * @brief 向JSON数组添加数值元素
 *
 * @param array JSON数组
 * @param value 数值
 */
void json_array_append_number(JsonArray *array, double value)
{
    if (array && array->cjson)
    {
        cJSON_AddItemToArray(array->cjson, cJSON_CreateNumber(value));
    }
}

/**
 * @brief 向JSON数组添加布尔元素
 *
 * @param array JSON数组
 * @param value 布尔值
 */
void json_array_append_bool(JsonArray *array, bool value)
{
    if (array && array->cjson)
    {
        cJSON_AddItemToArray(array->cjson, cJSON_CreateBool(value));
    }
}

/**
 * @brief 向JSON数组添加null元素
 *
 * @param array JSON数组
 */
void json_array_append_null(JsonArray *array)
{
    if (array && array->cjson)
    {
        cJSON_AddItemToArray(array->cjson, cJSON_CreateNull());
    }
}

/**
 * @brief 向JSON数组添加JSON对象
 *
 * @param array JSON数组
 * @param value 要添加的JSON对象（所有权转移给数组）
 */
void json_array_append_object(JsonArray *array, JsonObject *value)
{
    if (array && array->cjson && value && value->cjson)
    {
        cJSON_AddItemToArray(array->cjson, value->cjson);
        value->auto_free = false; // 所有权转移
    }
}

/**
 * @brief 向JSON数组添加子数组
 *
 * @param array JSON数组
 * @param value 要添加的子数组（所有权转移给父数组）
 */
void json_array_append_array(JsonArray *array, JsonArray *value)
{
    if (array && array->cjson && value && value->cjson)
    {
        cJSON_AddItemToArray(array->cjson, value->cjson);
        value->auto_free = false; // 所有权转移
    }
}

/**
 * @brief 从JSON数组获取字符串元素
 *
 * @param array         JSON数组
 * @param index         元素索引
 * @param default_value 默认值（当索引越界或类型错误时返回）
 * @return const char*  字符串值
 */
const char *json_array_get_string(JsonArray *array, int index, const char *default_value)
{
    if (!array || !array->cjson || index < 0 || index >= json_array_size(array))
    {
        return default_value;
    }

    cJSON *item = cJSON_GetArrayItem(array->cjson, index);
    if (cJSON_IsString(item))
    {
        return item->valuestring;
    }
    return default_value;
}

/**
 * @brief 从JSON数组获取数值元素
 *
 * @param array         JSON数组
 * @param index         元素索引
 * @param default_value 默认值（当索引越界或类型错误时返回）
 * @return double       数值
 */
double json_array_get_number(JsonArray *array, int index, double default_value)
{
    if (!array || !array->cjson || index < 0 || index >= json_array_size(array))
    {
        return default_value;
    }

    cJSON *item = cJSON_GetArrayItem(array->cjson, index);
    if (cJSON_IsNumber(item))
    {
        return item->valuedouble;
    }
    return default_value;
}

/**
 * @brief 从JSON数组获取布尔元素
 *
 * @param array         JSON数组
 * @param index         元素索引
 * @param default_value 默认值（当索引越界或类型错误时返回）
 * @return bool         布尔值
 */
bool json_array_get_bool(JsonArray *array, int index, bool default_value)
{
    if (!array || !array->cjson || index < 0 || index >= json_array_size(array))
    {
        return default_value;
    }

    cJSON *item = cJSON_GetArrayItem(array->cjson, index);
    if (cJSON_IsBool(item))
    {
        return cJSON_IsTrue(item);
    }
    return default_value;
}

/**
 * @brief 从JSON数组获取JSON对象元素
 *
 * @param array JSON数组
 * @param index 元素索引
 * @return JsonObject* JSON对象（不转移所有权），失败返回NULL
 */
JsonObject *json_array_get_object(JsonArray *array, int index)
{
    if (!array || !array->cjson || index < 0 || index >= json_array_size(array))
    {
        return NULL;
    }

    cJSON *item = cJSON_GetArrayItem(array->cjson, index);
    if (cJSON_IsObject(item))
    {
        return create_json_object(item, false);
    }
    return NULL;
}

/**
 * @brief 从JSON数组获取子数组元素
 *
 * @param array JSON数组
 * @param index 元素索引
 * @return JsonArray* 子数组（不转移所有权），失败返回NULL
 */
JsonArray *json_array_get_array(JsonArray *array, int index)
{
    if (!array || !array->cjson || index < 0 || index >= json_array_size(array))
    {
        return NULL;
    }

    cJSON *item = cJSON_GetArrayItem(array->cjson, index);
    if (cJSON_IsArray(item))
    {
        return create_json_array(item, false);
    }
    return NULL;
}